﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Media;
using System.Collections.ObjectModel;
using System.Data;
using System.Windows.Media.Imaging;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows.Controls;
using System.Globalization;
using produccion.modelo;
using produccion.AccesoDatos;
using produccion.clases;
using System.Windows.Input;
using System.Collections.Specialized;

namespace produccion.vistamodelo
{
    class VMMantenimientodeControl : ViewModelBase
    {

        #region Campos

            private List<CLSCONTROLP> _liscontrol = new List<CLSCONTROLP>();
            private ProcesoProduccionRepositorio _repositorio = new ProcesoProduccionRepositorio();

        #endregion

        #region Constructor
            
            public VMMantenimientodeControl()
            {
                try
                {
                    consultarControles();
                    liscontroles.CollectionChanged += OnCollectionChanged;

                    if (MDOgeneral.conexion == null || MDOgeneral.conexion.State == ConnectionState.Closed)
                    {
                        MDOgeneral.conectar();
                    }
                    strTituloVentana = "Mantenimiento de control - Usuario: " + MDOgeneral.usuario + " - [frmMantenimientodeControl]";
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }

        #endregion

        #region Interfaces publicas

            private string _strTituloVentana;
            public string strTituloVentana
            {
                get { return _strTituloVentana; }
                set { _strTituloVentana = value; base.OnPropertyChanged("strTituloVentana"); }
            }

            public List<CLSCONTROLP> liscontrol
            {
                get { return _liscontrol; }
                set { _liscontrol = value; base.OnPropertyChanged("liscontrol"); }
            }

            private MDOgeneral.mensaje _msn = new MDOgeneral.mensaje();
            public MDOgeneral.mensaje msn
            {
                get { return _msn; }
                set { _msn = value; base.OnPropertyChanged("msn"); }
            }

            private ObservableCollection<VMControl> _liscontroles = new ObservableCollection<VMControl>();
            public ObservableCollection<VMControl> liscontroles
            {
                get { return _liscontroles; }
                set { _liscontroles = value; base.OnPropertyChanged("liscontroles"); }
            }

            private VMControl _selcontrol;
            public VMControl selcontrol
            {
                get { return _selcontrol; }
                set { _selcontrol = value; base.OnPropertyChanged("selcontrol"); }
            }

            private Boolean _logValido;
            public Boolean logValido
            {
                get { return _logValido; }
                set { _logValido = value; base.OnPropertyChanged("logValido"); }
            }

        #endregion

        #region Comandos
            
            RelayCommand _cmdSalir;
            public ICommand cmdSalir
            {
                get
                {
                    if (_cmdSalir == null)
                    {
                        _cmdSalir = new RelayCommand(Salir);
                    }
                    return _cmdSalir;
                }
            }

            RelayCommand _cmdEliminar;
            public ICommand cmdEliminar
            {
                get
                {
                    if (_cmdEliminar == null)
                    {
                        _cmdEliminar = new RelayCommand(r => eliminarControl());
                    }
                    return _cmdEliminar;
                }
            }

            RelayCommand _cmdGrabar;
            public ICommand cmdGrabar
            {
                get
                {
                    if (_cmdGrabar == null)
                    {
                        _cmdGrabar = new RelayCommand(r => grabarControl());
                    }
                    return _cmdGrabar;
                }
            }

        #endregion

        #region Metodos

            public void consultarControles()
            {
                try
                {
                    liscontrol = new CLSCONTROLP().LisControles();
                    List<VMControl> all = (from con in liscontrol select new VMControl(con)).ToList();
                    foreach (VMControl con in all)
                    {
                        con.validarControl += validaControl;
                        con.PropertyChanged += OnPropertyChanged;
                    }

                    liscontroles = new ObservableCollection<VMControl>(all);
                    liscontroles.CollectionChanged += OnCollectionChanged;
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }

            void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
            {
                try
                {
                    logValido = ((from con in liscontroles where con.IsValid.Equals(false) select con.IsValid).ToList().Count()) > 0 ? true : false;
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }

            void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
            {
                try
                {
                    if (e.NewItems != null && e.NewItems.Count > 0)
                    {
                        foreach (VMControl con in e.NewItems)
                        {
                            con.validarControl += validaControl;
                            con.PropertyChanged += OnPropertyChanged;
                        }
                    }
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }

            public string validaControl(string id_con, string cod_con)
            {
                try
                {
                    int i = (from con in liscontroles where con.id_con.Equals(id_con.Trim()) && con.cod_con.Equals(cod_con.Trim()) select con).ToList().Count();
                    if (i > 1)
                    {
                        return "Clave primaria ya existe.";
                    }
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
                return null;
            }

            private void grabarControl()
            {
                try
                {
                    List<CLSCONTROLP> lstAgregar = (from con in liscontroles where con.agregar.Equals(true) select con.getControles()).ToList();
                    List<CLSCONTROLP> lstActualizar = (from con in liscontroles where con.actualizar.Equals(true) select con.getControles()).ToList();
                    List<CLSCONTROLP> lstEliminar = (from con in liscontroles where con.eliminar.Equals(true) select con.getControles()).ToList();

                    if (_repositorio.guardarControl(lstActualizar, lstEliminar, lstAgregar))
                    {
                        msn.texto = "La información de controles se guardo con exito.";
                        msn.tipo = true;
                        consultarControles();
                    }
                    else
                    {
                        msn.texto = "La información de controles no se pudo guardar.";
                        msn.tipo = false;
                    }
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }

            private void eliminarControl()
            {
                try
                {
                    if (selcontrol.agregar)
                        liscontroles.Remove(selcontrol);
                    else
                        selcontrol.eliminar = !selcontrol.eliminar;
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }

            public void Salir(object frmformulario)
            {
                try
                {
                    ((Window)frmformulario).Close();
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }
            
        #endregion
    }

    public class VMControl : ViewModelBase, IDataErrorInfo
    {
        #region Campos
        
            private CLSCONTROLP _controles = new CLSCONTROLP();
            public delegate string validarCodigoControl(string id_con, string cod_con);

        #endregion

        #region Constructor
            
            public VMControl(CLSCONTROLP controles)
            {
                _controles = controles;
            }

            public VMControl()
            {
                agregar = true;
                base.OnPropertyChanged("id_con");
                base.OnPropertyChanged("cod_con");
            }

        #endregion

        #region Interfaces publicas

            public validarCodigoControl validarControl;

            public string id_con
            {
                get { return _controles.ID_CON; }
                set 
                {
                    if (agregar == true)
                    {
                        _controles.ID_CON = value;
                        base.OnPropertyChanged("id_con");
                    }
                }
            }

            public string cod_con
            {
                get { return _controles.COD_CON; }
                set 
                {
                    if (agregar == true)
                    {
                        _controles.COD_CON = value;
                        base.OnPropertyChanged("cod_con");
                    }
                }
            }

            public string nom_con
            {
                get { return _controles.NOM_CON; }
                set 
                {
                    if (_controles.NOM_CON != value && agregar == false)
                        actualizar = true;
                    _controles.NOM_CON = value;
                    base.OnPropertyChanged("nom_con");
                }
            }

            public string des_con
            {
                get { return _controles.DES_CON; }
                set 
                {
                    if (_controles.DES_CON != value && agregar == false)
                        actualizar = true;
                    _controles.DES_CON = value;
                    base.OnPropertyChanged("des_con");
                }

            }

            private bool _actualizar = false;
            public bool actualizar
            {
                get { return _actualizar; }
                set { _actualizar = value; base.OnPropertyChanged("actualizar"); }
            }

            private bool _eliminar = false;
            public bool eliminar
            {
                get { return _eliminar; }
                set { _eliminar = value; base.OnPropertyChanged("eliminar"); }
            }

            private bool _agregar = false;
            public bool agregar
            {
                get { return _agregar; }
                set { _agregar = value; base.OnPropertyChanged("agregar"); }
            }

        #endregion

        #region Metodos
            
            public CLSCONTROLP getControles()
            {
                return _controles;
            }
            
        #endregion

        #region IDataErrorInfo Members

            string IDataErrorInfo.Error { get { return null; } }

            string IDataErrorInfo.this[string propertyName]
            {
                get { return this.GetValidationError(propertyName); }
            }

        #endregion

        #region Validation

            /// <summary>
            /// Returns true if this object has no validation errors.
            /// </summary>
            /// 

            public bool IsValid
            {
                get
                {
                    foreach (string property in ValidatedProperties)
                        if (GetValidationError(property) != null)
                            return false;

                    return true;
                }
            }

            static readonly string[] ValidatedProperties = 
                    { 
                        "id_con",
                        "cod_con",
                        "nom_con",
                        "des_con"
                    };

            string GetValidationError(string propertyName)
            {
                if (Array.IndexOf(ValidatedProperties, propertyName) < 0)
                    return null;

                string error = null;

                switch (propertyName)
                {
                    case "id_con":
                        error = this.ValidateId();
                        break;
                    case "cod_con":
                        error = this.Validatecodigo();
                        break;
                    case "nom_con":
                        error = this.Validatenom_con();
                        break;
                    case "des_con":
                        error = this.Validatedes_con();
                        break;    
                    default:
                        Debug.Fail("Unexpected property being validated on Customer: " + propertyName);
                        break;
                }
                return error;
            }

            string ValidateId()
            {
                try
                {
                    if (id_con == null) { return "Debe ingresar el id de control."; }
                    if (id_con != null)
                    {
                        if (id_con.Trim().Length > 3) { return "El id de control no puede tener más de tres caracteres."; }
                    }
                    
                    return null;
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
                return null;
            }

            string Validatecodigo()
            {
                try
                {
                    if (cod_con==null) { return "Debe ingresar el codigo de control."; }
                    if (cod_con != null)
                    {
                        if (cod_con.Length > 3) { return "El código de control no puede tener más de 3 caracteres."; }
                        string error = null;
                        error = validarControl(id_con, cod_con);

                        if (!String.IsNullOrEmpty(error))
                        {
                            return error;
                        }
                        return null;
                    }
                    
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
                return null;
            }

            string Validatenom_con()
            {
                try
                {
                    if (nom_con == null) { return "Debe ingresar el nombre del control"; }
                    if (nom_con != null)
                    {
                        if (nom_con.Trim().Length > 100) { return "El nombre de control no puede tener más de 100 caracteres."; }
                    }
                    return null;
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
                return null;
            }

            string Validatedes_con()
            {
                try
                {
                    if (des_con == null) { return "Debe ingresar la descripción del control"; }
                    if (des_con != null)
                    {
                        if (des_con.Length > 200) { return "El nombre de control no puede tener más de 200 caracteres."; }
                    }
                    return null;
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
                return null;
            }

        #endregion
    }
}
